<template>
  <el-upload
    action="#"
    class="upload"
    :drag="true"
    :multiple="false"
    :show-file-list="false"
    :http-request="uploadExcel"
    :before-upload="beforeExcelUpload"
    :on-exceed="handleExceed"
    :on-success="excelUploadSuccess"
    :on-error="excelUploadError"
    :accept="fileType.join(',')"
  >
    <slot name="empty">
      <el-icon class="el-icon--upload">
        <upload-filled />
      </el-icon>
      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
    </slot>
    <template #tip>
      <slot name="tip">
        <div class="el-upload__tip">
          支持PDF、DOC、PPT、JPG、PNG格式；最多可上传{{ totalCount }}个文件；总大小不超过{{ totalFileSize }}G
        </div>
      </slot>
    </template>
  </el-upload>
</template>

<script setup lang="ts" name="ImportExcel">
import { ref } from "vue";
import { ElNotification, UploadRequestOptions, UploadRawFile } from "element-plus";

export interface UploadFileProps {
  title: string; // 标题
  totalFileSize?: number; // 总共上传的文件大小，单位G
  fileSize?: number; // 上传文件的大小
  fileType?: any[]; // 上传文件的类型
  importApi?: (params: any) => Promise<any>; // 批量导入的Api
  getTableList?: () => void; // 获取表格数据的Api
  totalCount?: number; //可上传的最大文件个数
  fileList?: any[]; // 已上传的文件列表
}

// 是否覆盖数据
const isCover = ref(false);
// 上传的文件
const fileName = ref("");
// 父组件传过来的参数
const props = withDefaults(defineProps<UploadFileProps>(), {
  totalFileSize: 1,
  title: "",
  // fileSize: 5,
  fileType: () => [
    "application/pdf",
    "application/msword",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "application/vnd.ms-powerpoint",
    "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    "image/jpeg",
    "image/png"
  ],
  totalCount: 10,
  fileList: () => []
});

// 文件上传
const uploadExcel = async (param: UploadRequestOptions) => {
  let excelFormData = new FormData();
  excelFormData.append("file", param.file);
  excelFormData.append("isCover", isCover.value as unknown as Blob);
  props.importApi!(excelFormData).then(({ data }) => {
    const list = {
      ...data,
      size: param.file.size
    };
    // 更新父组件的fileList
    emit("updateFileList", list);
  });
};

/**
 * @description 文件上传之前判断
 * @param file 上传的文件
 * */
const beforeExcelUpload = (file: UploadRawFile) => {
  fileName.value = file.name;
  const isCount = props.fileList.length < props.totalCount;
  const isType = props.fileType!.includes(file.type);
  const fileSize = props.fileList.reduce((sum, e) => sum + Number(e.size || 0), file.size);
  const isSize = fileSize / 1024 / 1024 / 1024 < props.totalFileSize!;
  if (!isCount)
    ElNotification({
      title: "温馨提示",
      message: `最多可上传 ${props.totalCount} 个文件`,
      type: "warning"
    });
  if (!isType)
    ElNotification({
      title: "温馨提示",
      message: "上传文件只支持PDF、DOC、PPT、JPG、PNG格式！",
      type: "warning"
    });
  if (!isSize)
    setTimeout(() => {
      ElNotification({
        title: "温馨提示",
        message: `上传文件总大小不能超过 ${props.totalFileSize}G！`,
        type: "warning"
      });
    }, 0);
  return isCount && isType && isSize;
};

// 文件数超出提示
const handleExceed = () => {
  ElNotification({
    title: "温馨提示",
    message: `最多只能上传 ${props.totalCount} 个文件！`,
    type: "warning"
  });
};

// 上传错误提示
const excelUploadError = () => {
  ElNotification({
    title: "温馨提示",
    message: `文件 ${fileName.value} 上传失败，请您重新上传！`,
    type: "error"
  });
};

// 上传成功提示
const excelUploadSuccess = () => {
  ElNotification({
    title: "温馨提示",
    message: `文件 ${fileName.value} 上传成功！`,
    type: "success"
  });
};

const emit = defineEmits(["updateFileList"]);
</script>
<style lang="scss" scoped></style>
